// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: donggu

#pragma once
#include <experimental/filesystem>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "coin2/exchange/base/market/market_exchange_api.h"

namespace coin2::flow {

class SymbolGroupConfig {
 public:
  explicit SymbolGroupConfig(
      const std::experimental::filesystem::path& toml_path = "data/coin2/feed/symbol_groups.toml");
  std::vector<char> GetGroups(const MarketExchangeApi& mea) const;
  char GetGroupForRelativeNorm(const MarketExchangeApi& mea, const std::string& symbol) const;
  const std::vector<std::string>& GetRelativeNormSymbols(const MarketExchangeApi& mea, char group)
      const;
  const std::vector<std::string>& GetAllRelativeNormSymbols(const MarketExchangeApi& mea)
      const;

  static const SymbolGroupConfig& GetInstance() {
    if (config_ == nullptr) {
      config_ = std::make_unique<SymbolGroupConfig>();
    }
    return *config_;
  }

  static const SymbolGroupConfig& ResetInstance(
      const std::experimental::filesystem::path& toml_path = "data/coin2/feed/symbol_groups.toml") {
    config_ = std::make_unique<SymbolGroupConfig>(toml_path);
    return *config_;
  }

 private:
  using SymbolGroupMap = std::unordered_map<std::string, char>;
  using SymbolTable = std::map<char, std::vector<std::string>>;

  mutable std::vector<std::string> all_symbols_;
  std::unordered_map<MarketExchangeApi, SymbolGroupMap> map_;
  std::unordered_map<MarketExchangeApi, SymbolTable> table_;
  static std::unique_ptr<SymbolGroupConfig> config_;
};

}  // namespace coin2::flow
